#include "head.h"
#include "transFile.h"

int recv_once(int sockFd, train_t *ptrain, long total){
    ssize_t ret = recvn(sockFd, &ptrain->length, sizeof(ptrain->length));
    ERROR_CHECK(ret, -1, "recvn");
    //printf("train->length = %d\n", ptrain->length);

    ret = recvn(sockFd, &ptrain->data, sizeof(ptrain->data));
    ERROR_CHECK(ret, -1, "recvn");
    //printf("train->data = %s\n", ptrain->data);

    ret = recvn(sockFd, &ptrain->code, sizeof(ptrain->code));
    ERROR_CHECK(ret, -1, "recvn");
    //printf("train->code = %d\n", ptrain->code);

    return 0;
}

int recvn(int sockFd, void *buf, long total){
    //netFd - sockFd, buf - 缓冲区首地址, total - 接收文件总大小
    char *p = (char *)buf;
    long curSize = 0;
    while(curSize < total){
        ssize_t ret = recv(sockFd, p+curSize, total-curSize, 0);
        ERROR_CHECK(ret, -1, "recv");
        if(0 == ret){
            return 1;
        }
        curSize += ret;
    }
    return 0;
}

int recvFile(int sockFd, train_t *ptrain){
    train_t train;
    //1、接收文件名
    char filename[4096] = {0};
    recvn(sockFd, &train.length, sizeof(train.length));//文件名的长度
    recvn(sockFd, &train.data, train.length);//文件名
    memcpy(filename, train.data, train.length);
    printf("recv filename = %s\n", filename);

    //2、接收文件大小
    off_t fileSize;
    recvn(sockFd, &train.length, sizeof(train.length));
    recvn(sockFd, &train.data, train.length);
    memcpy(&fileSize, train.data, train.length);
    printf("recv fileSize = %ld\n", fileSize);

    //3、接收文件
    int fd = open(filename, O_CREAT|O_RDWR|O_TRUNC, 0666);
    ftruncate(fd, fileSize);
    char *p = (char *)mmap(NULL, fileSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    ERROR_CHECK(p, MAP_FAILED, "mmap");
    recvn(sockFd, p, fileSize);
    munmap(p, fileSize);
    printf("recvFile done!\n");
    close(fd);

    return 0;
}

int sendFile(int sockFd, train_t *ptrain){}

// int parseStr(char beforeParseStr[], char* afterParseStr[], int *argcNum, train_t *ptrain){
//     *argcNum = 0;
//     char* token = NULL;
//     const char p[] = " ";
//     token = strtok(beforeParseStr, p);
//     size_t len = strcspn(token, "\n");  // 查找换行符的位置
//     if (token[len] == '\n') {
//         token[len] = '\0';  // 将换行符替换为字符串结束符
//     }
//     printf("token = %s\n", token);
//     afterParseStr[*argcNum] = token;
//     if((strcmp(token, "ls\n")) == 0){
//         ptrain->code = LS_APPLY;
//     }
//     else if(strcmp(token, "cd\n") == 0){
//         ptrain->code = CD_APPLY;
//     }
//     else if((strcmp(token, "pwd")) == 0){
//         ptrain->code = PWD_APPLY;
//     }
//     else if((strcmp(token, "puts\n")) == 0){
//         ptrain->code = PUTS_APPLY;
//     }
//     else if((strcmp(token, "gets\n")) == 0){
//         ptrain->code = GETS_APPLY;
//     }
//     else if((strcmp(token, "rm\n")) == 0){
//         ptrain->code = RM_APPLY;
//     }
//     else if(strcmp(token, "mkdir") == 0){
//         ptrain->code = MKDIR_APPLY;
//     }
//     else if((strcmp(token, "rmdir\n")) == 0){
//         ptrain->code = RMDIR_APPLY;
//     }
//     else{
//         printf("输入指令错误, 请重新输入!\n");
//         return -1;
//     }
//     //printf("afterParseStr[%d] = %s", *argcNum, afterParseStr[*argcNum]);
//     ++(*argcNum);
//     token = strtok(NULL, " ");
//     while (token != NULL)
//     {
//         token = strtok(beforeParseStr, " ");
//         afterParseStr[*argcNum] = token;
//         //printf("afterParseStr[%d] = %s\n", *argcNum, afterParseStr[*argcNum]);
//         ++(*argcNum);
//     }
//     return 0;
// }

void remove_newline(char *str) {
    size_t len = strcspn(str, "\n");
    if (str[len] == '\n') {
        str[len] = '\0';
    }
}

int parseStr(char beforeParseStr[], char* afterParseStr[], int *argcNum, train_t *ptrain) {
    *argcNum = 0;
    char* token = NULL;
    const char p[] = " ";
    token = strtok(beforeParseStr, p);

    if (token == NULL) {
        printf("输入指令错误, 请重新输入!\n");
        return -1;
    }

    remove_newline(token);
    printf("token = %s\n", token);
    afterParseStr[*argcNum] = token;

    if (strcmp(token, "ls") == 0) {
        ptrain->code = LS_APPLY;
    } 
    else if (strcmp(token, "cd") == 0) {
        ptrain->code = CD_APPLY;
    } 
    else if (strcmp(token, "pwd") == 0) {
        ptrain->code = PWD_APPLY;
    } 
    else if (strcmp(token, "puts") == 0) {
        ptrain->code = PUTS_APPLY;
    } 
    else if (strcmp(token, "gets") == 0) {
        ptrain->code = GETS_APPLY;
    } 
    else if (strcmp(token, "rm") == 0) {
        ptrain->code = RM_APPLY;
    } 
    else if (strcmp(token, "mkdir") == 0) {
        ptrain->code = MKDIR_APPLY;
    } 
    else if (strcmp(token, "rmdir") == 0) {
        ptrain->code = RMDIR_APPLY;
    } 
    else {
        printf("输入指令错误, 请重新输入!\n");
        return -1;
    }

    ++(*argcNum);
    token = strtok(NULL, p);
    while (token != NULL) {
        remove_newline(token);
        afterParseStr[*argcNum] = token;
        ++(*argcNum);
        token = strtok(NULL, p);
    }

    return 0;
}